package sc.client;

import java.io.FileReader;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.LogManager;
import java.util.logging.Logger;

import k8.k8;

import sc.client.world.Avatar;
import sc.client.world.Container;
import sc.nio.NioClient;
import sc.nio.NioConnection;

public final class Client
{
	// Version of MMO Client
	public static final String VERSION = "mmo client 0.01";

	// Client properties file
	private static final String PROPERTIES_FILE = "client.properties";

	// The Logger instance accessible to all
	public static Logger logger = null;

	// The client properties
	public static Properties properties;

	// Non-blocking server communicator
	public static ServerIO serverio;

	// The players avatar.
	public static Avatar avatar;

	// Map of all known Containers
	public static Map<String, List<Container>> containers = new HashMap<String, List<Container>>();

	// Scale of coordinates i.e. A Container with x = 100, is OpenGL x-axis = 1
	public static int SCALE = 100;

	/**
	 * Program entry method.
	 */
	public static void main(String[] args)
	{
		FileReader reader;
		String host;
		int port;

		try
		{
			// Configure java.util.logging and get a Logger instance
			System
					.setProperty("java.util.logging.config.file",
							PROPERTIES_FILE);
			LogManager logManager = LogManager.getLogManager();
			logManager.readConfiguration();
			logger = Logger.getLogger("");

			// Read the properties configuration
			reader = new FileReader(PROPERTIES_FILE);
			Client.properties = new Properties();
			Client.properties.load(reader);

			// Get server location
			host = properties.getProperty("sc.server.host");
			port = Integer.parseInt(Client.properties
					.getProperty("sc.server.port"));

			// Log start header info
			logger.info("Client version             : " + Client.VERSION);

			// Create an NioClient instance and start its thread
			NioClient nioclient = new NioClient();
			nioclient.setLogIO(true);
			NioConnection nioconnection = nioclient.connect(InetAddress.getByName(host), port);
			Thread t = new Thread(nioclient);
			t.setDaemon(true);
			t.start();

			// Create the OpenGL display context
			k8.initialise(Client.VERSION, 800, 600);

			// Create an instance of Avatar to hold the players own avatar
			Client.avatar = new Avatar(Client.properties
					.getProperty("user.name"));
			// Add to all known containers
			List<Container> objectlist = new ArrayList<Container>();
			objectlist.add(Client.avatar);
			Client.containers.put(Client.avatar.getID(), objectlist);

			// Create and register the NioReader
			serverio = new ServerIO(nioconnection);

			FPS.initialise();
			Interface.initialise();

			// Send a connection request to the server
			serverio.writeConnect();

			// Start the application main loop
			k8.run();

		}
		catch (Exception e)
		{
			String indent = "";
			Client.logger.severe(e.getLocalizedMessage());
			for (StackTraceElement element : e.getStackTrace())
			{
				Client.logger.severe(indent + (indent.equals("") ? "" : "\\- ")
						+ element.getClassName() + "."
						+ element.getMethodName());
				indent += " ";
			}
		}
		finally
		{
			k8.destroy();
		}
	}
}
